<template>
  <el-date-picker
    v-model="modelValueCustomer" :type="props.type"
    :clearable="props.clearable"
    :disabled-date="disabledDate"
    :value-format="currentValueFormat"
    :editable="props.clearable"
    placeholder="选择日期"
    start-placeholder="开始日期"
    end-placeholder="结束日期"
    :shortcuts="_shortcuts"
    @calendar-change="calendarChange"
  />
</template>

<script lang="ts" setup>
import { computed, onMounted, withDefaults } from 'vue'
import moment from 'moment'
import { ObjectUtil } from '@utils/object-util'

type optionalScopeType = 'before' | 'after' | 'none'

const props = withDefaults(defineProps<{
  modelValue?: string | string[],
  clearable?: boolean,
  start?: string,
  end?: string,
  defaultDate?: string | string[] | number
  type?: 'year'|'month'|'date'|'datetime'|'week'|'datetimerange'|'daterange'|'monthrange',
  valueFormat?: string,
  optionalScope?: optionalScopeType,
  days?: number,
  shortcuts?: number[]
}>(), {
  clearable: false,
  type: 'date',
  optionalScope: 'before'
})

const emits = defineEmits(['update:modelValue', 'update:start', 'update:end'])

const typeValueFormatDic = {
  year: 'YYYY',
  month: 'YYYY-MM',
  date: 'YYYY-MM-DD',
  datetime: 'YYYY-MM-DD HH:mm:ss',
  week: 'YYYY-MM-DD',
  datetimerange: 'YYYY-MM-DD HH:mm:ss',
  daterange: 'YYYY-MM-DD',
  monthrange: 'YYYY-MM'
}
const currentValueFormat = ref<any>('')

const typeArrayDic = ['datetimerange', 'daterange', 'monthrange']

// 双向绑定
const modelValueCustomer = computed({
  get (): any {
    if (typeArrayDic.includes(props.type)) {
      return props.modelValue || [props.start || '', props.end || '']
    } else {
      return props.modelValue || ''
    }
  },
  set (val) {
    setModelValue(val)
  }
})

/**
 * 设置并格式化modelValue值
 * @param val
 */
function setModelValue (val: string | string[]) {
  if (typeArrayDic.includes(props.type)) {
    if (val) {
      let start = val[0] || ''
      let end = val[1] || ''
      if (props.type === 'monthrange') {
        if (['YYYY-MM-DD', 'YYYY-MM-DD HH:mm:ss'].includes(currentValueFormat.value)) {
          start = moment(val[0]).format('YYYY-MM-01')
          const endMoment = moment(val[1])
          end = endMoment.format('YYYY-MM-') + endMoment.daysInMonth()
        }
        if (currentValueFormat.value === 'YYYY-MM-DD HH:mm:ss') {
          start += ' 00:00:00'
          end += ' 23:59:59'
        }
      } else if (props.type === 'daterange' && currentValueFormat.value === 'YYYY-MM-DD HH:mm:ss') {
        start = moment(val[0]).format('YYYY-MM-DD 00:00:00')
        end = moment(val[1]).format('YYYY-MM-DD 23:59:59')
      }
      emits('update:start', start)
      emits('update:end', end)
      emits('update:modelValue', [start, end])
    } else {
      emits('update:start', '')
      emits('update:end', '')
      emits('update:modelValue', val)
    }
  } else {
    emits('update:modelValue', val)
  }
}

// 默认值
onMounted(() => {
  currentValueFormat.value = props.valueFormat || typeValueFormatDic[props.type]
  if (props.defaultDate !== undefined) {
    if (typeArrayDic.includes(props.type)) {
      if (Array.isArray(props.defaultDate)) {
        setModelValue([props.defaultDate[0], props.defaultDate[1]])
      } else if (ObjectUtil.isNumber(props.defaultDate)) {
        setModelValue([
          moment().subtract(props.defaultDate, props.type === 'monthrange' ? 'months' : 'days').format(currentValueFormat.value),
          moment().format(currentValueFormat.value)
        ])
      }
    } else if (ObjectUtil.isString(props.defaultDate)) {
      setModelValue(props.defaultDate)
    }
  }
  initShortcuts()
})

// region TODO 限制范围
let startTime = 0
const calendarChange = (e: Date[]) => {
  if (props.days && !e[1]) {
    startTime = e[0].getTime()
  } else {
    startTime = 0
  }
}
const oneDay = 86400000
const disabledDate = (date: Date) => {
  const today = new Date(moment().format('YYYY-MM-DD 00:00:00')).getTime()
  switch (props.optionalScope) {
    case 'before':
      if (date.getTime() > today) return true
      break
    case 'after':
      if (date.getTime() < today) return true
  }
  if (startTime && props.days) {
    const minDate = startTime - oneDay * (props.days - 1)
    const maxDate = startTime + oneDay * (props.days - 1)
    return date.getTime() < minDate || date.getTime() > maxDate
  }
  return false
}
// endregion

// region TODO 快捷选择
const _shortcuts = ref([])
const shortcutsDic = {
  0: '今天',
  '-1': '昨天',
  1: '明天'
}
function initShortcuts () {
  if (props.shortcuts && ['datetimerange', 'daterange'].includes(props.type)) {
    const shortcutsTemp = []
    for (let i = 0, len = props.shortcuts.length; i < len; i++) {
      const number = props.shortcuts[i]
      let text = shortcutsDic[number]
      const start = new Date()
      const end = new Date()
      if (!text) {
        if (number > 0) {
          text = '未来' + number + '天'
          end.setDate(end.getDate() + number - 1)
        } else {
          text = '近' + -number + '天'
          start.setDate(end.getDate() + number + 1)
        }
      } else {
        start.setDate(start.getDate() + number)
        end.setDate(end.getDate() + number)
      }
      shortcutsTemp.push({
        text,
        value: [start, end]
      })
    }
    _shortcuts.value = shortcutsTemp
  }
}
// endregion

</script>

<style lang="scss" scoped>
</style>
